﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace RNT.Common.Utils
{
    public class BitMap
    {
        /// <summary>
        /// 图片缩放
        /// </summary>
        /// <param name="bmpSource">源图片</param>
        /// <param name="bmpSize">缩放图片的大小</param>
        /// <returns>缩放的图片</returns>
        public static Bitmap BitMapZoom(Bitmap bmpSource, int bmpWidth, int bmpHeight)
        {
            Bitmap bmp, zoomBmp;
            try
            {
                bmp = new Bitmap(bmpSource);
                zoomBmp = new Bitmap(bmpWidth, bmpHeight);
                Graphics gh = Graphics.FromImage(zoomBmp);
                gh.InterpolationMode = InterpolationMode.HighQualityBicubic;
                gh.DrawImage(bmp, new Rectangle(0, 0, bmpWidth, bmpHeight), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);

                gh.Dispose();
                return zoomBmp;
            }
            catch
            { }
            finally
            {
                bmp = null;
                zoomBmp = null;
                GC.Collect();
            }
            return null;
        }


        public static Bitmap ScaleZoom(Bitmap bmp, int size)
        {
            if (bmp != null)
            {
                double zoomScale;
                if (bmp.Width > size || bmp.Height > size)
                {
                    double imageScale = (double)bmp.Width / (double)bmp.Height;
                    double thisScale = 1;

                    if (imageScale > thisScale)
                    {
                        zoomScale = (double)size / (double)bmp.Width;
                        return BitMapZoom(bmp, size, (int)(bmp.Height * zoomScale));
                    }
                    else
                    {
                        zoomScale = (double)size / (double)bmp.Height;
                        return BitMapZoom(bmp, (int)(bmp.Width * zoomScale), size);
                    }
                }
            }
            return bmp;
        }

        /// <summary>
        /// 加图片水印
        /// </summary>
        /// <param name="img">要加水印的原图?(System.Drawing)</param>
        /// <param name="filename">文件名</param>
        /// <param name="watermarkFilename">水印文件名</param>
        /// <param name="watermarkStatus">图片水印位置1=左上 2=中上 3=右上 4=左中  5=中中 6=右中 7=左下 8=右中 9=右下</param>
        /// <param name="quality">加水印后的质量0~100,数字越大质量越高</param>
        /// <param name="watermarkTransparency">水印图片的透明度1~10,数字越小越透明,10为不透明</param>
        public static void ImageWaterMarkPic(Image img, string filename, string watermarkFilename, int watermarkStatus, int quality, int watermarkTransparency)
        {
            Graphics g = Graphics.FromImage(img);
            //设置高质量插值法
            //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //设置高质量,低速度呈现平滑程度
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            Image watermark = new Bitmap(watermarkFilename);

            if (watermark.Height >= img.Height || watermark.Width >= img.Width)
                return;

            ImageAttributes imageAttributes = new ImageAttributes();
            ColorMap colorMap = new ColorMap();

            colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
            colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
            ColorMap[] remapTable = { colorMap };

            imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

            float transparency = 0.5F;
            if (watermarkTransparency >= 1 && watermarkTransparency <= 10)
                transparency = (watermarkTransparency / 10.0F);


            float[][] colorMatrixElements = {
                                                new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                                new float[] {0.0f,  0.0f,  0.0f,  transparency, 0.0f},
                                                new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                            };

            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            int xpos = 0;
            int ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 2:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 3:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 4:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 5:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 6:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 7:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 8:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 9:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
            }

            g.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType.IndexOf("jpeg") > -1)
                    ici = codec;
            }
            EncoderParameters encoderParams = new EncoderParameters();
            long[] qualityParam = new long[1];
            if (quality < 0 || quality > 100)
                quality = 80;

            qualityParam[0] = quality;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
            encoderParams.Param[0] = encoderParam;

            if (ici != null)
                img.Save(filename, ici, encoderParams);
            else
                img.Save(filename);

            g.Dispose();
            img.Dispose();
            watermark.Dispose();
            imageAttributes.Dispose();
        }

        /// <summary>
        /// 增加图片文字水印
        /// </summary>
        /// <param name="img">要加水印的原图?(?System.Drawing)</param>
        /// <param name="filename">文件名</param>
        /// <param name="watermarkText">水印文字</param>
        /// <param name="watermarkStatus">图片水印位置1=左上 2=中上 3=右上 4=左中  5=中中 6=右中 7=左下 8=右中 9=右下</param>
        /// <param name="quality">加水印后的质量0~100,数字越大质量越高</param>
        /// <param name="fontname">水印的字体</param>
        /// <param name="fontsize">水印的字号</param>
        public static void ImageWaterMarkText(Image img, string filename, string watermarkText, int watermarkStatus, int quality, string fontname, int fontsize)
        {
            Graphics g = Graphics.FromImage(img);
            Font drawFont = new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Pixel);
            SizeF crSize;
            crSize = g.MeasureString(watermarkText, drawFont);

            float xpos = 0;
            float ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (float)img.Width * (float).01;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 2:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = (float)img.Height * (float).01;
                    break;
                case 3:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 4:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 5:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 6:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 7:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 8:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 9:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
            }

            //g.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + 1, ypos + 1);文字阴影
            g.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos);

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType.IndexOf("jpeg") > -1)
                    ici = codec;
            }
            EncoderParameters encoderParams = new EncoderParameters();
            long[] qualityParam = new long[1];
            if (quality < 0 || quality > 100)
                quality = 80;

            qualityParam[0] = quality;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
            encoderParams.Param[0] = encoderParam;

            if (ici != null)
                img.Save(filename, ici, encoderParams);
            else
                img.Save(filename);

            g.Dispose();
            img.Dispose();
        }

        /// <summary>
        /// tif 格式转 jpg 格式
        /// </summary>
        /// <param name="tifPath"></param>
        /// <param name="tifName"></param>
        /// <param name="delSource"></param>
        /// <returns></returns>
        public static bool TifToJpg(string tifPath, string tifName, bool delSource)
        {
            try
            {
                int len = tifPath.LastIndexOf(".tif");
                string fileName2 = tifPath.Substring(0, len);
                string filePath = fileName2.Substring(0, fileName2.LastIndexOf('\\') + 1);
                FileStream stream = File.OpenRead(tifPath);
                Bitmap bmp = new Bitmap(stream);
                System.Drawing.Image image = bmp;
                Guid objGuid = image.FrameDimensionsList[0];
                FrameDimension objDimension = new FrameDimension(objGuid);
                int totFrame = image.GetFrameCount(objDimension);

                for (int i = 0; i < totFrame; i++)//循环生成多张图片
                {
                    image.SelectActiveFrame(objDimension, i);
                    image.Save(filePath + tifName + "(" + i + ").jpg", ImageFormat.Jpeg);
                }
                bmp.Dispose();
                image.Dispose();
                stream.Close();
                if (delSource)
                {
                    File.Delete(tifPath);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        [DllImportAttribute("gdi32.dll")]
        private static extern bool BitBlt(
            IntPtr hdcDest, //目标设备的句柄   
            int nXDest, // 目标对象的左上角的X坐标   
            int nYDest, // 目标对象的左上角的X坐标   
            int nWidth, // 目标对象的矩形的宽度   
            int nHeight, // 目标对象的矩形的长度   
            IntPtr hdcSrc, // 源设备的句柄   
            int nXSrc, // 源对象的左上角的X坐标   
            int nYSrc, // 源对象的左上角的X坐标   
            Int32 dwRop // 光栅的操作值   
        );

        [DllImportAttribute("gdi32.dll")]
        private static extern IntPtr CreateDC(
            string lpszDriver, // 驱动名称   
            string lpszDevice, // 设备名称   
            string lpszOutput, // 无用，可以设定位"NULL"   
            IntPtr lpInitData // 任意的打印机数据   
        );



        public Bitmap GetFullScreen()
        {
            try
            {
                IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);
                //创建显示器的DC   
                Graphics g1 = Graphics.FromHdc(dc1);
                //由一个指定设备的句柄创建一个新的Graphics对象   
                Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
                //根据屏幕大小创建一个与之相同大小的Bitmap对象   
                Graphics g2 = Graphics.FromImage(bmp);
                //获得屏幕的句柄   
                IntPtr dc3 = g1.GetHdc();
                //获得位图的句柄   
                IntPtr dc2 = g2.GetHdc();
                //把当前屏幕捕获到位图对象中   
                BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);
                //把当前屏幕拷贝到位图中   
                g1.ReleaseHdc(dc3);
                //释放屏幕句柄   
                g2.ReleaseHdc(dc2);
                //释放位图句柄   

                /*
                 * 当然你也可以根据自己的需要，把屏幕以其他图片的格式来保存，
                 * 如果你想把图片保存为位图文件，可以把"ImageFormat.Jpeg"改换成"ImageFormat.Bmp"；
                 * 想把图片保存为Gif文件，就把"ImageFormat.Jpeg"改换成"ImageFormat.Gif"。
                 * 你可以保存的文件类型大概有十多种，这里就不一一介绍了，当然你也要相应改变保存文件的后缀。
                 */
                //MyImage.Save("d:\\MyJpeg.png", ImageFormat.Png); 
                return bmp;
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
    }
}
